package il.ac.technion.cs236700.address_book;

import il.ac.technion.cs236700.utils.BadData;

import java.util.Map;


/**
 * This is a faked implementation of the {@link AddressBook} interface - it merely
 * illustrates the functionality of the AddressBook object for a limited
 * set of predefined inputs (see {@link Samples}).
 * 
 * As such, this faked object cannot handle arbitrary data or arbitrary 
 * sequences of method invocations. Each time this object receives a request
 * which exceeds its envelope of legal states it throws 
 * a {@link NonSimulated} exception.
 */
public class FakedAddressBook implements AddressBook {
   
   
   /**
    * This exception is thrown when {@link FakedAddressBook} receives a 
    * request which exceeds its limited envelope of legal state. Remember that
    * {@link FakedAddressBook} is merely a simulator so it does not know how
    * to handle arbitrary sequences of requests.
    */
   public static class NonSimulated extends RuntimeException  {
      private static final long serialVersionUID = -17722884656713481L; 
      
      public NonSimulated() {
         super("This Mock object cannot handle the data you provided");
      }
   }

   private static final String[] SUPPORTED = {      
      "First Name", 
      "Last Name", 
      "Home Phone",
      "Mobile Phone",
      "Work Phone",
      "Fax",
      "Email",
      "Instant Messanger Type",
      "Instant Messanger ID",
      "Home Address",
      "Work Address",
      "Home page",
      "Title",
      "Company" };
      
   
   private String input;
   private String[] outputFields;
   private Map<String,String> map;
   private Person person;
   private Address home;
   private Address work;
   
   public String[] getSupportedKeys() {
      return SUPPORTED;
   }

   public String getNormalized() {
      if(Samples.DECKARD.equals(person) && Samples.LAPD.equals(work) 
         && home == null)
         return Samples.CSV8;
      
      if(Samples.MAP1.equals(map)) {
         if(outputFields == Samples.FIELDS_4)
            return Samples.CSV7;
         throw new NonSimulated();
      }
      
      if(input == Samples.CSV1) {
         if(outputFields == Samples.FIELDS_1)
            return Samples.CSV2;
         if(outputFields == Samples.FIELDS_2)
            return Samples.CSV3;
      }
            
      throw new NonSimulated();
   }

   public void load(String csv) {
      input = csv;
   }

   public void setOutput(String... fields) {
      for(String f : fields) {
         boolean found = false;
         for(String curr : getSupportedKeys())
            found |= curr.equals(f);
         if(!found)
            throw new BadData("Field " + f + " is not supported");
      }
            
      outputFields = fields;
   }

   public String getConflicts() {
      if(input == Samples.CSV4 && outputFields == Samples.FIELDS_3)
         return Samples.CSV5;
      
      throw new NonSimulated();
   }

   public void add(Map<String, String> map_) {
      map = map_;
   }

   public void add(Person p_, Address home_, Address work_) {
      person = p_;
      home = home_;
      work = work_;
   }
}
